package oa.hleast.xswl.controller.app.oms;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import oa.hleast.common.result.Result;
import oa.hleast.common.web.util.RequestUtils;
import oa.hleast.xswl.common.enums.OrderStatusEnum;
import oa.hleast.xswl.common.enums.PayTypeEnum;
import oa.hleast.xswl.pojo.domain.oms.OmsOrder;
import oa.hleast.xswl.pojo.domain.oms.OmsOrderDelivery;
import oa.hleast.xswl.pojo.domain.oms.OmsOrderItem;
import oa.hleast.xswl.pojo.dto.oms.OrderConfirmDTO;
import oa.hleast.xswl.pojo.dto.oms.OrderSubmitDTO;
import oa.hleast.xswl.pojo.form.oms.OrderCommentForm;
import oa.hleast.xswl.pojo.vo.oms.*;
import oa.hleast.xswl.service.oms.IOrderDeliveryService;
import oa.hleast.xswl.service.oms.IOrderItemService;
import oa.hleast.xswl.service.oms.IOrderService;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


/**
 * @author 00209
 * @email dz@hleast.com
 * @date 2021/04/12
 */
@Api(tags = "【移动端】订单服务")
@RestController("AppOrderController")
@RequestMapping("/api.app/v1/orders")
@Slf4j
@AllArgsConstructor
public class OrderController {

    private final IOrderService orderService;
    private final IOrderItemService orderItemService;
    private final IOrderDeliveryService orderDeliveryService;

    @ApiOperation(value = "手动支付回调")
    @PostMapping("/manual/callback")
    public Result<Boolean> manualCallback(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        return Result.success();
    }

    @RequestMapping(value = "/wx/callback", method = {org.springframework.web.bind.annotation.RequestMethod.POST, org.springframework.web.bind.annotation.RequestMethod.GET})
    @ResponseBody
    public void payNotify(HttpServletRequest request, HttpServletResponse response) {
        orderService.wxPayNotify(request, response);

    }


    @ApiOperation(value = "支付宝支付回调")
    @PostMapping("/alipay/callback")
    public Result alipayCallback(Map<String, Object> param) {
        log.info("支付宝支付回调 param = {},currentTime = {}", param, System.currentTimeMillis());
        return Result.success();
    }

    @ApiOperation("订单列表")
    @GetMapping
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", defaultValue = "1", value = "页码", paramType = "query", dataType = "Long", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "limit", defaultValue = "10", value = "每页数量", paramType = "query", dataType = "Long", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "orderSn", value = "订单编号", paramType = "query", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "status", value = "订单状态", paramType = "query", dataType = "OrderStatusEnum", dataTypeClass = OrderStatusEnum.class)
    })
    public Result<List<OmsOrderVo>> list(@RequestParam(defaultValue = "1") Long page,
                                         @RequestParam(defaultValue = "10") Long limit,
                                         @RequestParam(required = false) String orderSn,
                                         @RequestParam(required = false) Integer status) {
        Long userId = RequestUtils.getUserId();
        log.info("status = {}", status);

        IPage<OmsOrder> result = orderService.page(new Page<>(page, limit), new LambdaQueryWrapper<OmsOrder>()
                .eq(StrUtil.isNotBlank(orderSn), OmsOrder::getOrderSn, orderSn)
                .eq(ObjectUtil.isNotNull(status), OmsOrder::getStatus, status)
                .eq(OmsOrder::getMemberId, userId)
                .orderByDesc(OmsOrder::getGmtCreate)
        );

        List<OmsOrderVo> voList = new ArrayList<>();
        for (OmsOrder omsOrder : result.getRecords()) {
            OmsOrderVo vo = new OmsOrderVo();
            BeanUtil.copyProperties(omsOrder, vo);
            vo.setOrderItems(orderItemService.list(new LambdaQueryWrapper<OmsOrderItem>().eq(OmsOrderItem::getOrderId, omsOrder.getId())));
            // 是否显示查看物流信息按钮  条件1:待收货  条件2:商家填写了物流信息
            int count = orderDeliveryService.count(new LambdaQueryWrapper<OmsOrderDelivery>()
                    .eq(OmsOrderDelivery::getOrderId, omsOrder.getId())
            );
            log.info("count = {}", count);
            if (count > 0 && omsOrder.getStatus() >= OrderStatusEnum.DELIVERED.getCode()) {
                vo.setWhetherDelivery(true);
            }
            voList.add(vo);
        }

        log.info("voList = {}", voList);
        return Result.success(voList, result.getTotal());
    }

    @ApiOperation("订单详情")
    @ApiImplicitParam(name = "orderDetail", value = "订单详情", required = true, paramType = "path", dataType = "OmsOrder", dataTypeClass = OmsOrder.class)
    @GetMapping("/{orderId}/_detail")
    public Result<OmsOrderVo> detail(@PathVariable Long orderId) {


        return Result.success(orderService.detail(orderId));
    }

    @ApiOperation("订单确认")
    @ApiImplicitParam(name = "orderConfirm", value = "确认订单信息", required = true, paramType = "body", dataType = "OrderConfirmDTO", dataTypeClass = OrderConfirmDTO.class)
    @PostMapping("/_confirm")
    public Result<OrderConfirmVO> confirm(@RequestBody OrderConfirmDTO orderConfirm) {
        OrderConfirmVO result = orderService.confirm(orderConfirm);
        return Result.success(result);
    }

    @ApiOperation("订单提交")
    @ApiImplicitParam(name = "orderSubmitDTO", value = "提交订单信息", required = true, paramType = "body", dataType = "OrderSubmitDTO", dataTypeClass = OrderSubmitDTO.class)
    @PostMapping("/_submit")
    public Result submit(@Valid @RequestBody OrderSubmitDTO orderSubmitDTO) {
        OrderSubmitVO result = orderService.submit(orderSubmitDTO);
        return Result.success(result);
    }

    @ApiOperation("订单金额")
    @ApiImplicitParam(name = "OrderInfoVO", value = "提交订单信息", required = true, paramType = "path", dataType = "OrderInfoVO", dataTypeClass = OrderInfoVO.class)
    @GetMapping("/{orderId}/_info")
    public Result info(@PathVariable Long orderId) {
        OrderInfoVO orderInfoVO = orderService.info(orderId);
        return Result.success(orderInfoVO);
    }

    @ApiOperation("订单支付")
    @PostMapping("/{orderId}/_pay")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单ID", paramType = "path", dataType = "Long", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "payType", value = "支付方式", paramType = "query", dataType = "Integer", dataTypeClass = Integer.class)
    })
    public Result pay(@PathVariable Long orderId, @RequestParam Integer payType) {
        log.info("orderId = {},payType = {}", orderId, payType);
        PayTypeEnum payTypeEnum = PayTypeEnum.getByCode(payType);
        switch (payTypeEnum) {
            case WEIXIN:
                String result = orderService.payByWeiXin(orderId);
                return Result.success(result);
            case ALIPAY:
                orderService.payByAlipay(orderId);
                break;
            case BALANCE:
                orderService.pay(orderId);
                break;
            case POINT:
                orderService.payPoint(orderId);
                break;
            default:
                return Result.failed("系统暂不支持该支付方式~");
        }
        return Result.success();
    }

    @ApiOperation("订单取消")
    @PostMapping("/{orderId}/_cancel")
    @ApiImplicitParam(name = "orderId", value = "订单ID", paramType = "path", dataType = "Long", dataTypeClass = Long.class)
    public Result cancelOrder(@PathVariable Long orderId) {
        boolean result = orderService.cancelOrder(orderId);
        return Result.judge(result);
    }

    @ApiOperation("订单删除")
    @PostMapping("/{orderId}/_delete")
    @ApiImplicitParam(name = "orderId", value = "订单ID", paramType = "path", dataType = "Long", dataTypeClass = Long.class)
    public Result deleteOrder(@PathVariable Long orderId) {
        boolean result = orderService.deleteOrder(orderId);
        return Result.judge(result);
    }

    @ApiOperation("订单确认收货")
    @PostMapping("/{orderId}/_receipt")
    @ApiImplicitParam(name = "orderId", value = "订单ID", paramType = "path", dataType = "Long", dataTypeClass = Long.class)
    public Result receipt(@PathVariable Long orderId) {
        boolean result = orderService.receipt(orderId);
        return Result.judge(result);
    }

    @ApiOperation("订单物流查询")
    @PostMapping("/{orderId}/_findDelivery")
    @ApiImplicitParam(name = "orderId", value = "订单ID", paramType = "path", dataType = "Long", dataTypeClass = Long.class)
    public Result _findDelivery(@PathVariable Long orderId) {
        String result = orderService.findDelivery(orderId);
        return Result.success(result);
    }

    @ApiOperation("根据相关Id获取用户订单，主要针对营销场订单")
    @PostMapping("/{relativeId}/_countByRelativeId")
    @ApiImplicitParam(name = "orderId", value = "相关ID", paramType = "path", dataType = "Long", dataTypeClass = Long.class)
    public Result _countByRelativeId(@PathVariable Long relativeId) {
        Long memberId = RequestUtils.getUserId();
        Integer result = orderService.count(new LambdaQueryWrapper<OmsOrder>().eq(OmsOrder::getMemberId, memberId)
                .eq(OmsOrder::getRelativeId, relativeId));
        return Result.success(result);
    }


    /**
     * 根据订单ID获取商品列表
     */
    @ApiOperation("根据订单ID获取商品列表")
    @ApiImplicitParam(name = "orderId", value = "相关ID", paramType = "query", dataType = "Long", dataTypeClass = Long.class)
    @GetMapping("/findSpuByOrderId")
    public Result<ShowOrderVo> findSpuByOrderId(@RequestParam Long orderId) {
        ShowOrderVo result = orderService.findSpuByOrderId(orderId);


        return Result.success(result);
    }

    /**
     * 保存订单商品评论
     */
    @ApiOperation("保存订单商品评论")
    @PostMapping("/saveComment")
    public Result<ShowOrderVo> saveComment(@RequestBody OrderCommentForm form) {
        Boolean result = orderService.saveComment(form);

        return Result.judge(result);
    }

    /**
     * 我的评论
     */
    @ApiOperation("我的评论")
    @GetMapping("/findMyComment")
    public Result<List<OmsOrderCommentVo>> findMyComment(@RequestParam Integer page, @RequestParam Integer limit) {
        Page<OmsOrderCommentVo> result = orderService.findMyComment(page, limit);

        return Result.success(result.getRecords(), result.getTotal());
    }

    /**
     * 商品所有的评论列表
     */
    @ApiOperation("商品所有的评论列表")
    @ApiImplicitParam(name = "spuId", value = "相关ID", paramType = "query", dataType = "Long", dataTypeClass = Long.class)
    @GetMapping("/findAllComment")
    public Result<List<OmsOrderCommentVo>> findAllComment(@RequestParam Long spuId, @RequestParam Integer page, @RequestParam Integer limit) {
        Page<OmsOrderCommentVo> result = orderService.findCommentBySpuId(spuId, page, limit);

        return Result.success(result.getRecords(), result.getTotal());
    }

    /**
     * 退款售后状态
     */
    @ApiOperation("退款售后状态")
    @ApiImplicitParam(name = "orderId", value = "订单ID", paramType = "query", dataType = "Long", dataTypeClass = Long.class)
    @GetMapping("/refundAndAfterSale")
    public Result<List<RefundAndAfterSaleVo>> refundAndAfterSale(@RequestParam Long orderId) {
        List<RefundAndAfterSaleVo> result = orderService.refundAndAfterSale(orderId);

        return Result.success(result);
    }
}
